
from ..BaseCore.Selenium电商抽象类 import ShopOnline_CreateProduct
from ..BaseCore.Selenium电商抽象类 import WebDriver,WebElement,Service,Options,By
from ..BaseCore.Selenium电商抽象类 import abstractmethod
import json,typing,pathlib


def group_by_key(
    items: typing.List[typing.Dict[str, typing.Any]],
    key_path: str, 
    sep: str = "."  # 路径分隔符，默认用.分隔嵌套层级
) -> typing.Dict[typing.Any, typing.List[typing.Dict[str, typing.Any]]]:
    """
    按指定键（支持嵌套路径）对字典列表进行分组，保持原始数据结构不变
    
    Args:
        items: 原始字典列表（支持嵌套字典结构）
        key_path: 分组依据的键路径（如单层键"price"，或嵌套键"parent.child"）
        sep: 路径分隔符，默认用.分隔（可自定义为其他符号如/）
    
    Returns:
        分组后的字典，键为路径对应的取值，值为包含原始字典的列表（数据结构不变）
    
    Raises:
        ValueError: 当键路径不存在或数据结构不匹配时抛出
    """
    groups = {}
    # 拆分路径为层级列表（如"a.b.c"拆分为["a", "b", "c"]）
    keys = key_path.split(sep)
    
    for item in items:
        current = item  # 用于逐层遍历嵌套结构
        try:
            # 按路径逐层获取值（处理嵌套）
            for key in keys:
                current = current[key]
            # 此时current就是路径对应的最终值（分组依据）
            group_key = current
        except (KeyError, TypeError) as e:
            # KeyError：路径中的某个键不存在
            # TypeError：中间节点不是字典（无法继续取值）
            raise ValueError(f"键路径 '{key_path}' 在元素 {item} 中无效：{str(e)}")
        
        # 按最终取值分组，保留原始item（数据结构不变）
        if group_key not in groups:
            groups[group_key] = []
        groups[group_key].append(item)

    return groups


class TaoBao(ShopOnline_CreateProduct):
    def __init__(self):
        super().__init__()

    
    def LoadConfigFile(self, config_file = "config.json") -> typing.Self:
        """加载配置文件"""
        from ..BaseCore.ConfigManager import ConfigManager
        self.config = ConfigManager().load_config(config_file)
        # self.config : dict = json.load(fp=open(file=config_file, mode="r", encoding="utf-8"))
        self.fristcatgeory = self.config["tb_fristcatgeory"]
        self.secondcatgeory = self.config["tb_secondcatgeory"]
        self.thirdcatgeory = self.config["tb_thirdcatgeory"]
        self.fourthcatgeory = self.config['tb_fourthcatgeory']
        self.producttitle = self.config['tb_producttitle']
        
        self.main_images = self.config.get("main_images",[])
        self.detail_images = self.config.get("detail_images",[])
        self.sku_images = self.config.get("sku_images",[])        
        self.main_video = self.config.get("main_video","")
        
        self.attributes = self.config.get("tb_attributes",[])
        self.materials = self.config.get("tb_materials",[])
        self.number = self.config.get("tb_number",10000)
        
        self.sizes = self.config.get("tb_sizes",{})
        self.size_chart = self.config.get("tb_size_chart",[])
        return self


    def OpenCreateProductPage(self) -> typing.Self:
        """打开创建产品页面"""
        self.log.info(f"正在打开淘宝创建产品页面!")
        
        _Create_Product_Page = "https://item.upload.taobao.com/sell/ai/category.htm"
        self.driver.switch_to.new_window("tab")
        self.driver.get(url=_Create_Product_Page)
        
        self.log.info(f"当前页面 Url : {self.driver.current_url}")
        
        return self

    def SelectCategoryMode(self) -> typing.Self:
        """选择模式"""
        
        self.log.info(f"正在选择 [搜索发品] 模式创建商品!")
        
        # 切换选择页面
        if not self.finder.verify_element(xpath="//div[contains(@class,'active-tab')]/div[text()='搜索发品']",timeout=5):
            self.finder.chain_find_element_safe(xpath="//div[contains(@class,'item-tab')]//div[text()='搜索发品']")
            self.mouse.chain_safe_click()
        if not self.finder.verify_element(xpath="//div[@class='cate-content']"):
            self.finder.chain_find_element_safe(xpath="//*[text()='选择类目']")
            self.mouse.chain_safe_click()

        return self

    def SelectFirstCategory(self) -> typing.Self:
        """选择一级分类"""
        if self.fristcatgeory:
            
            self.log.info(f"正在选择一级分类 [ {self.fristcatgeory} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='category-list'])[1]//*[text()='{self.fristcatgeory}']")
            self.mouse.chain_safe_click()
        
        return self


    def SelectSecondCategory(self) -> typing.Self:
        """选择二级分类"""
        if self.secondcatgeory:
            
            self.log.info(f"正在选择二级分类 [ {self.secondcatgeory} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='category-list'])[2]//*[text()='{self.secondcatgeory}']")
            self.mouse.chain_safe_click()
        
        return self


    def SelectThirdCategory(self) -> typing.Self:
        """选择三级分类"""
        if self.thirdcatgeory:
            
            self.log.info(f"正在选择三级分类 [ {self.thirdcatgeory} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='category-list'])[3]//*[text()='{self.thirdcatgeory}']")
            self.mouse.chain_safe_click()
        
        return self


    def SelectfourthCategory(self) -> typing.Self:
        """选择四级分类"""
        if self.fourthcatgeory:
            
            self.log.info(f"正在选择四级分类 [ {self.fourthcatgeory} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='category-list'])[4]//*[text()='{self.fourthcatgeory}']")
            self.mouse.chain_safe_click()

        return self

    def FillProductBrand(self) -> typing.Self:
        """填写产品品牌"""
        
        if self.finder.chain_find_element_safe(xpath="//div[@role='row']//input[@role='combobox']").parent.current_element:
            
            self.log.info(f"正在填写产品品牌 [ 无品牌/无注册商标 ]!")
            
            # 外部输入框
            self.mouse.chain_safe_click()
        
            # 内部输入框
            self.finder.chain_find_element_safe(xpath="//div[@class='sell-o-select-options']//div[@class='options-search']//input")
            self.keyboard.chain_send_keys(InputValue="无品牌/无注册商标")
        
            # 内部选择选项
            self.finder.chain_find_element_safe(xpath="//div[@class='sell-o-select-options']/div[@class='options-content']//div[@class='options-item']/div[@class='sell-o-info']/div[@class='info-content'][text()='无品牌/无注册商标']")
            self.mouse.chain_safe_click()
        return self

    def GotoParamSettingPage(self) -> typing.Self:
        """跳转到参数设置页面"""
        
        self.log.info(f"正在跳转到参数设置页面!")
        
        self.finder.chain_find_element_safe(xpath="//button[not(@disabled)]//span[text()='确认，下一步']")
        self.mouse.chain_safe_click()
        
        return self


    def FillProductTitle(self) -> typing.Self:
        """填写产品标题"""
        
        self.log.info(f"正在填写产品标题 [ {self.producttitle} ]!")
        
        if self.finder.chain_find_element_safe(xpath="//div[@id='struct-title']//input").parent.current_element:
            self.keyboard.chain_condition_input(InputValue=self.producttitle,condition_xpath=f"//div[@class='sell-component-tbtitle']//input[@value='{self.producttitle}']")
        
        return self


    def FillProductParams(self) -> typing.Self:
        """填写产品参数"""
        
        self.log.info(f"正在填写产品参数!")
        
        for attributeitem in self.attributes:
            attributeName = attributeitem["attribute"]
            attributeValue = attributeitem["value"]
            
            self.log.info(f"正在填写产品参数 [ {attributeName} ] [ {attributeValue} ]!")
            
            if isinstance(attributeValue, str):
                if self.finder.chain_find_element_safe(xpath=f"//div[@class='default-items flex-item']/div[.//span[text()='{attributeName}']]//input[@role='combobox']").parent.current_element:
                    self.mouse.chain_safe_click()
                
                if self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-search']//input"):
                    self.keyboard.chain_safe_input(InputValue=attributeValue)
                
                if self.finder.chain_find_element_safe(xpath=f"//div[@class='options-content']//div[@class='options-item']/div[@class='sell-o-info']//div[@class='info-content'][text()='{attributeValue}']"):
                    self.mouse.chain_safe_click()
            
            if isinstance(attributeValue, list):
                if self.finder.chain_find_element_safe(xpath=f"//div[@class='default-items flex-item']/div[.//span[text()='{attributeName}']]//input[@role='combobox']").parent.current_element:
                    self.mouse.chain_safe_click()
                
                for value in attributeValue:
                    if self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-search']//input"):
                        self.keyboard.chain_safe_input(InputValue=value)
                
                    if self.finder.chain_find_element_safe(xpath=f"//div[@class='options-content']//div[@class='options-item']/div[@class='sell-o-info']//div[@class='info-content'][text()='{value}']"):
                        self.mouse.chain_safe_click()
                        
            
        return self


    def FillProductMaterial(self) -> typing.Self:
        """填写产品材质"""
        
        self.log.info(f"正在填写产品材质!")
        
        for index,materialitem in enumerate(self.materials):
            materialName = materialitem["material"]
            materialValue = materialitem["value"]
            
            self.log.info(f"正在填写产品材质 [ {materialName} ] [ {materialValue} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"//div[@class='material-content']//button")
            self.mouse.chain_safe_click()
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='material-content']//div[@class='material-item'])[{index + 1}]")
            self.mouse.chain_safe_click()
            
            self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-search']//input")
            self.keyboard.chain_safe_input(InputValue=materialName)
            self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-content']//div[@class='options-item']//div[text()='{materialName}']")
            self.mouse.chain_safe_click()
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='material-content']//div[@class='material-item'])[{index + 1}]//span[@class='input-wrap']//input")
            self.keyboard.chain_safe_input(InputValue=materialValue)
        
        
        return self


    def FillProductMainImage(self) -> typing.Self:
        """填写产品主图"""
        
        self.log.info(f"正在填写产品主图!")
        self.log.info(f"主图数量 : {len(self.main_images)}")
        self.log.info(f"图片列表 : {self.main_images}")
        
        self.log.info("正在打开主图图片对话框面板!")
        self.finder.chain_find_element_safe(xpath="//div[@id='struct-mainImagesGroup']//div[@class='image-list']/div[@class='drag-item']")
        self.mouse.chain_condition_click(condition_xpath="//iframe[@id='mainImagesGroup']")
        
        self.log.info("正在切换框架!")
        self.driver.switch_to.frame(self.finder.find_element(xpath="//iframe[@id='mainImagesGroup']"))
        
        self.log.info("正在打开文件上传对话框面板!")
        self.finder.chain_find_element_safe(xpath="//button/span[text()='本地上传']")
        self.mouse.chain_condition_click(condition_xpath="//input[@type='file'][contains(@accept,'image')]")
        
        self.log.info("正在关闭系统对话框!")
        self.base.Close_Browser_Dialog()
        
        self.log.info(f"正在上传图片 : {'\n'.join(self.main_images)}")
        self.finder.chain_find_element_safe(xpath="//input[@type='file'][@multiple][contains(@accept,'image')]")
        self.keyboard.chain_send_keys(InputValue="\n".join(self.main_images))
        
        self.log.info("正在等待图片上传完成!")
        self.finder.verify_element(xpath="//div[@role='dialog']//div[contains(@class,'actions')]//span[contains(text(),'个文件上传成功')]",timeout=60)
        
        self.log.info("正在准备切换回")
        self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//div[contains(@class,'options')]//button/span[text()='完成']")
        self.mouse.chain_condition_click(condition_xpath="//input[@type='file']",expect_exists=False)
        self.base.wait(5)

        for index,mainItem in enumerate(self.main_images):
            imageName = pathlib.Path(mainItem).name
            
            self.log.info(f"正在选择第 {index + 1} / {len(self.main_images)} 张主图 [ {imageName} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='PicList_PicturesShow_main-show__QVvZn'])[position() <= {self.main_images.__len__()}][.//div[@class='PicList_tip_title__aQfti']][.//*[text()='{imageName}']]//img")
            self.mouse.chain_safe_click()

        self.log.info("正在切换回默认框架!")
        self.driver.switch_to.default_content()
        
        return self


    def FillProductDetailImage(self) -> typing.Self:
        """填写产品详情图"""
        
        self.log.info(f"正在填写产品详情图!")
        
        self.log.info("正在打开详情图片图片对话框面板!")
        self.finder.chain_find_element_safe(xpath="//div[@id='struct-descRepublicOfSell']//*[text()='图片']")
        self.mouse.chain_condition_click(condition_xpath="//iframe[@id='mainImagesGroup']")
        
        self.log.info("正在切换框架!")
        self.driver.switch_to.frame(self.finder.find_element(xpath="//div[@role='dialog']//iframe"))

        self.log.info("正在打开文件上传对话框面板!")
        self.finder.chain_find_element_safe(xpath="//button/span[text()='本地上传']")
        self.mouse.chain_condition_click(condition_xpath="//input[@type='file'][contains(@accept,'image')]")
        
        self.log.info("正在关闭系统对话框!")
        self.base.Close_Browser_Dialog()
        
        self.log.info(f"正在上传图片 : {'\n'.join(self.detail_images)}")
        self.finder.chain_find_element_safe(xpath="//input[@type='file'][@multiple][contains(@accept,'image')]")
        self.keyboard.chain_send_keys(InputValue="\n".join(self.detail_images))
        
        self.log.info("正在等待图片上传完成!")
        self.finder.verify_element(xpath="//div[@role='dialog']//div[contains(@class,'actions')]//span[contains(text(),'个文件上传成功')]",timeout=60)
        
        self.log.info("正在准备切换回")
        self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//div[contains(@class,'options')]//button/span[text()='完成']")
        self.mouse.chain_condition_click(condition_xpath="//input[@type='file']",expect_exists=False)
        self.base.wait(5)
        
        
        for index,mainItem in enumerate(self.detail_images):
            imageName = pathlib.Path(mainItem).name
            
            self.log.info(f"正在选择第 {index + 1} / {len(self.detail_images)} 张详情图 [ {imageName} ]!")
            
            self.finder.chain_find_element_safe(xpath=f"(//div[@class='PicList_PicturesShow_main-show__QVvZn'])[position() <= {self.detail_images.__len__()}][.//*[text()='{imageName}']]//img")
            self.mouse.chain_safe_click()


        self.finder.chain_find_element_safe(xpath="//button/span[contains(text(),'确定')]")
        self.mouse.chain_safe_click()
        
        self.log.info("正在切换回默认框架!")
        self.driver.switch_to.default_content()        
        return self


    def FillProductSku(self) -> typing.Self:
        """填写产品SKU"""
        
        self.log.info(f"正在填写产品SKU!")
        
        for index,skuitem in enumerate(self.sku_images):
            skuName = pathlib.Path(skuitem['path']).stem
            imagePath = skuitem['path']
            
            self.log.info(f"正在填写第 {index + 1} / {self.sku_images.__len__()} 个SKU [ {skuName} ]!")
            self.finder.chain_find_element_safe(xpath="//*[text()='销售属性']/following::input[@placeholder='主色(必选)'][@value='']")
            self.keyboard.chain_condition_input(InputValue=skuName,condition_xpath=f"//*[text()='销售属性']/following::input[@placeholder='主色(必选)'][@value='{skuName}']")
            
            self.log.info("正在打开Sku图片选择对话框面板!")
            self.finder.chain_find_element_safe(xpath=f"//*[text()='销售属性']/following::input[@placeholder='主色(必选)'][@value='{skuName}']/ancestor::*[position()<4]//div[@class='image-empty']")
            self.mouse.chain_script_click()
            
            self.log.info("正在切换到内部框架!")
            self.driver.switch_to.frame(self.finder.find_element(xpath="//iframe[@id='saleProps']"))
            
            self.log.info("正在打开文件上传对话框面板!")
            self.finder.chain_find_element_safe(xpath=f"//*[@class='right-btn btn']")
            self.mouse.chain_condition_click(condition_xpath="//input[@type='file']")
            
            self.log.info(f"正在上传 skuName {skuName} 对应的图片!")
            self.finder.chain_find_element_safe(xpath="//input[@type='file']")
            self.keyboard.chain_send_keys(InputValue=imagePath)
            self.finder.wait_element(xpath=f"//*[text()='销售属性']/following::input[@placeholder='主色(必选)'][@value='{skuName}']/ancestor::*[position()<4]//div[@class='image-empty']")
            
            self.log.info("正在切换回默认框架!")
            self.driver.switch_to.default_content()
            
            
            if index < self.sku_images.__len__()-1:
                self.log.info("开始填写下一个SKU!")
                
                self.finder.chain_find_element_safe(xpath="(//*[text()='销售属性']/following::input[@placeholder='主色(必选)']/following::button[contains(@class,'add')])[1]")
                self.mouse.chain_condition_click(condition_xpath="//*[text()='销售属性']/following::input[@placeholder='主色(必选)'][@value='']")
                            
        return self
            
    def FillProductSizes(self) -> typing.Self:
        """填写产品规格"""
        
        self.log.info("正在填写产品规格!")
        
        sizeType = self.sizes['type']
        sizeValues = self.sizes['values']

        self.finder.chain_find_element_safe(xpath="//*[text()='销售属性']/following::input[@placeholder='请选择尺码']")
        self.mouse.chain_condition_click(condition_xpath="//div[contains(@class,'opened')]")
        for index, sizeValue in enumerate(sizeValues):
            
            self.log.info(f"正在填写产品规格：{sizeValue}")
            self.finder.chain_find_element_safe(xpath=f"//div[contains(@class,'opened')]//label[not(contains(@class,'checked'))]//*[text()='{sizeValue}']")
            self.mouse.chain_condition_click(condition_xpath=f"//div[contains(@class,'opened')]//label[contains(@class,'checked')]//*[text()='{sizeValue}']")
            
            if index == len(sizeValues) -1:
                self.finder.chain_find_element_safe(xpath="//div[contains(@class,'opened')]//button/span[text()='确定']")
                self.mouse.chain_safe_click()
            
        return self
        

    def FillProductVideo(self) -> typing.Self:
        """填写产品视频"""

        if self.main_video:
            self.log.info("正在填写产品视频!")
            
        return self


    def FillProductPrice(self) -> typing.Self:
        """填写产品价格"""
        
        self.log.info("正在填写产品价格!")
        
        price_group = group_by_key(items=self.sku_images,key_path="price")
        
        for price in price_group:
            
            self.log.info(f"正在填写产品价格 : {price} 的商品")
            
            self.log.info("正在打开批量设置面板!")
            self.finder.chain_find_element_safe(xpath="//*[text()='销售规格']/following::button/span[text()='更多批量']")
            self.mouse.chain_condition_click(condition_xpath="//div[@role='dialog']")

            # 清空选择列表
            self.log.info("正在清空 Sku 列表!")
            self.finder.chain_find_element_safe(xpath=f"//div[@role='dialog']//*[text()='颜色分类']/following::*[@class='next-select-clear']/i")
            self.mouse.chain_safe_click()

            if price == max(price_group.keys(),key=lambda x: len(price_group[x])):                
                self.log.info(f"正在填写价格 {price}!")
                self.log.info(f"正在填写的Sku 列表数量 : {len(price_group[price])}!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='价格']/following::input)[1]")
                self.keyboard.chain_safe_input(InputValue=price)
                self.log.info("正在提交批量设置!")
                self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//button/span[text()='批量填充']")
                self.mouse.chain_safe_click()
                continue

            else:
                # 打开选项列表
                self.log.info("正在打开 Sku 选项列表!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='颜色分类']/following::input)[1]")
                self.mouse.chain_condition_click(condition_xpath=f"//div[@class='sell-o-select-options']/div[@class='options-search']//input")
                
                # 选择列表
                for index,skuitem in enumerate(price_group[price]):                
                    skuName = pathlib.Path(skuitem['path']).stem
                    
                    self.log.info(f"正在选择 价格为 [{price}]  SkuName [{skuName}] -- {index + 1} / {len(price_group[price])} !")
                    self.finder.chain_find_element_safe(xpath="//div[@class='sell-o-select-options']/div[@class='options-search']//input")
                    self.keyboard.chain_only_clear()
                    self.keyboard.chain_safe_input(InputValue=skuName)
                    self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-content']//div[text()='{skuName}']")
                    self.mouse.chain_safe_click()

                self.log.info(f"正在填写价格 {price}!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='价格']/following::input)[1]")
                self.keyboard.chain_safe_input(InputValue=price)
                
                self.log.info("正在提交批量设置!")
                self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//button/span[text()='批量填充']")
                self.mouse.chain_safe_click()

        return self


    def FillProductInventory(self) -> typing.Self:
        """填写产品库存"""
        
        self.log.info("正在填写产品库存!")
        
        # 打开对话框
        self.log.info("正在打开批量设置面板!")
        self.finder.chain_find_element_safe(xpath="//*[text()='销售规格']/following::button/span[text()='更多批量']")
        self.mouse.chain_condition_click(condition_xpath="//div[@role='dialog']")

        # 清空选择列表
        self.finder.chain_find_element_safe(xpath=f"//div[@role='dialog']//*[text()='颜色分类']/following::*[@class='next-select-clear']/i")
        self.mouse.chain_safe_click()

        # 填写数量
        self.log.info(f"正在填写库数量 {self.number}!")
        self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='数量']/following::input)[1]")
        self.keyboard.chain_safe_input(InputValue=self.number)

        # 批量填充
        self.log.info("正在提交批量设置!")
        self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//button/span[text()='批量填充']")
        self.mouse.chain_safe_click()
        


    def FillProductShopLabel(self) -> typing.Self:
        """填写产品商家编号"""
        code_group = group_by_key(items=self.sku_images,key_path="code")
        
        for code in code_group:
            
            self.log.info(f"正在填写产品商家编号：{code}")
            
            # 打开对话框
            self.log.info("正在打开批量设置面板!")
            self.finder.chain_find_element_safe(xpath="//*[text()='销售规格']/following::button/span[text()='更多批量']")
            self.mouse.chain_condition_click(condition_xpath="//div[@role='dialog']")

            # 清空选择列表
            self.log.info("正在清空 Sku 列表!")
            self.finder.chain_find_element_safe(xpath=f"//div[@role='dialog']//*[text()='颜色分类']/following::*[@class='next-select-clear']/i")
            self.mouse.chain_safe_click()

            if code == max(code_group.keys(),key=lambda x: len(code_group[x])):
                # 填写商家编号
                self.log.info(f"正在填写商家编号 {code}!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='商家编码']/following::input)[1]")
                self.keyboard.chain_safe_input(InputValue=code)
                
                # 批量填充
                self.log.info("正在提交批量设置!")
                self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//button/span[text()='批量填充']")
                self.mouse.chain_safe_click()
                continue
            
            else:
                # 打开选项列表
                self.log.info("正在打开 Sku 选项列表!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='颜色分类']/following::input)[1]")
                self.mouse.chain_condition_click(condition_xpath=f"//div[@class='sell-o-select-options']/div[@class='options-search']//input")

                # 选择列表
                for index,skuitem in enumerate(code_group[code]):
                    skuName = pathlib.Path(skuitem['path']).stem
                    
                    self.log.info(f"正在选择 编号为 [{code}]  SkuName [{skuName}] -- {index + 1} / {len(code_group[code])} !")
                    self.finder.chain_find_element_safe(xpath="//div[@class='sell-o-select-options']/div[@class='options-search']//input")
                    self.keyboard.chain_only_clear()
                    self.keyboard.chain_safe_input(InputValue=skuName)
                    self.finder.chain_find_element_safe(xpath=f"//div[@class='sell-o-select-options']/div[@class='options-content']//div[text()='{skuName}']")
                    self.mouse.chain_safe_click()

                # 填写商家编号
                self.log.info(f"正在填写商家编号 {code}!")
                self.finder.chain_find_element_safe(xpath="(//div[@role='dialog']//*[text()='商家编码']/following::input)[1]")
                self.keyboard.chain_safe_input(InputValue=code)
                
                # 批量填充
                self.log.info("正在提交批量设置!")
                self.finder.chain_find_element_safe(xpath="//div[@role='dialog']//button/span[text()='批量填充']")
                self.mouse.chain_safe_click()
                self.base.wait(1)

        return self


    def FillProductLogistics(self) -> typing.Self :
        """填写产品物流信息"""
        
        self.log.info("正在填写产品物流信息")
        
        # 选择发货时间
        self.finder.chain_find_element_safe(xpath=f"//*[text()='物流服务']/following::*[text()='发货时间']/following::*[text()='48小时内发货']")
        self.mouse.chain_safe_click()
        
        # 选择发货地址
        if self.finder.chain_find_element_safe(xpath="//*[text()='物流服务']/following::*[text()='提取方式']/following::*[@class='next-checkbox-wrapper'][.//*[text()='使用物流配送']]//input[@type='checkbox'][@aria-checked='false']").parent.current_element:
            self.mouse.chain_safe_click()
        self.finder.chain_find_element_safe(xpath="//*[text()='物流服务']/following::*[text()='运费模板']/following::input[@role='combobox']")
        self.mouse.chain_safe_click()
        self.finder.chain_find_element_safe(xpath=f"//div[@class='next-overlay-wrapper opened']//ul[@role='listbox']/li[@role='option']//span[text()='长美仓库发货']")
        self.mouse.chain_safe_click()
        
        
        
        return self

    def FillSizeCharts(self) -> typing.Self:
        """填写产品尺码表"""
        
        self.log.info("正在填写产品尺码表!")
        
        self.finder.chain_find_element_safe(xpath="//*[text()='商品尺寸表']/following::div[@class='next-table-inner']//table//tr//th[@label='身高']//input[@aria-checked='false']")
        self.mouse.chain_condition_click(condition_xpath="//*[text()='商品尺寸表']/following::div[@class='next-table-inner']//table//tr//th[@label='身高']//input[@aria-checked='true']")
        
        self.finder.chain_find_element_safe(xpath="//*[text()='商品尺寸表']/following::div[@class='next-table-inner']//table//tr//th[@label='体重']//input[@aria-checked='false']")
        self.mouse.chain_condition_click(condition_xpath="//*[text()='商品尺寸表']/following::div[@class='next-table-inner']//table//tr//th[@label='体重']//input[@aria-checked='true']")
        
        for sizeitem in self.size_chart:
            size = sizeitem['size']
            height_left,height_right = sizeitem["height"].split("-")
            weight_left,weight_right = sizeitem["weight"].split("-")
            
            self.log.info(f"正在填写尺码表：尺码 {size} 身高 {height_left}-{height_right} 体重 {weight_left}-{weight_right} !")
            
            self.finder.chain_find_element_safe(xpath=f"(//*[text()='商品尺寸表']/following::div[@class='next-table-body']//table//tr//td[@label='尺寸']//*[text()='{size}']/following::input[@placeholder='最小值'])[1]")
            self.keyboard.chain_safe_input(InputValue=height_left)
            self.finder.chain_find_element_safe(xpath=f"(//*[text()='商品尺寸表']/following::div[@class='next-table-body']//table//tr//td[@label='尺寸']//*[text()='{size}']/following::input[@placeholder='最大值'])[1]")
            self.keyboard.chain_safe_input(InputValue=height_right)
            
            self.finder.chain_find_element_safe(xpath=f"(//*[text()='商品尺寸表']/following::div[@class='next-table-body']//table//tr//td[@label='尺寸']//*[text()='{size}']/following::input[@placeholder='最小值'])[2]")
            self.keyboard.chain_safe_input(InputValue=weight_left)
            self.finder.chain_find_element_safe(xpath=f"(//*[text()='商品尺寸表']/following::div[@class='next-table-body']//table//tr//td[@label='尺寸']//*[text()='{size}']/following::input[@placeholder='最大值'])[2]")
            self.keyboard.chain_safe_input(InputValue=weight_right)
            
        
        return self